#ifndef _CONFSVR_CMD_HPP_20120614
#define _CONFSVR_CMD_HPP_20120614

#include "cmd_value.hpp"
#include "cmd_type.hpp"
#include "cmd_comm.hpp"

namespace cmd
{
	struct Host
	{
		public :
			std::string  _ip;
			uint32_t     _port;
		
		public :
			Host(): _ip(""), _port(0) {}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				return (str_sizeof(_ip) + sizeof(_port));
			}

	};

	struct AreaConf
	{
		public :
			AREAID        _area_id;
			ROOMNUM       _room_num;
			TABLENUM      _table_num;
		
		public :
			AreaConf() { memset(this, 0, sizeof(*this)); }

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				return (sizeof(_area_id) + sizeof(_room_num) + sizeof(_table_num));
			}
	};

	template <cmd_0_type cmd_0, cmd_1_type cmd_1>
	struct ConfigReqTmpl : public SSHead
	{
		public :
			uint16_t  _id;
			
		public :
			ConfigReqTmpl()
				: SSHead(cmd_0, cmd_1),
				  _id(0)
			{
			}
			
			uint32_t size() const
			{
				return (SSHead::size() + sizeof(_id));
			}

			void serialize(Streamer & streamer)
			{
				SSHead::serialize(streamer);
				streamer & _id;
			}

			const std::string to_string() const
			{
				std::ostringstream oss;
				oss << SSHead::to_string()
					<< " body: {id: " << (int)_id
					<< "}";
				return oss.str();
			}
	};

	struct CommonConf
	{
		public :
			uint32_t      _fixed_page_size;
			uint32_t      _fixed_capacity_size;

			uint32_t     _max_connection;
			uint32_t     _epoll_timeout;

		public :
			CommonConf()
				: _fixed_page_size(0),
				  _fixed_capacity_size(0),
				  _max_connection(0),
				  _epoll_timeout(0)
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				return (sizeof(_fixed_page_size) + sizeof(_fixed_capacity_size) +
						sizeof(_max_connection) + sizeof(_epoll_timeout));
			}
	};

	typedef ConfigReqTmpl<CONFSVR_CMD_0, SS_DBSVR_REQ> SSDBSvrReq;
	
	struct SSDBSvrRes : public SSHead
	{
		public :
			uint16_t      _err_code;

			CommonConf   _common;

			uint8_t      _thread_num;
			uint32_t     _thread_queue_size;
			uint32_t     _thread_page_size;
			uint32_t     _thread_capacity_size;

			Host         _service;

			// uint64_t     _mysql_host;
			std::string  _mysql_host;
			std::string  _mysql_user;
			std::string  _mysql_passwd;
			std::string  _mysql_dbname;

		public :
			SSDBSvrRes()
				: SSHead(CONFSVR_CMD_0, SS_DBSVR_RES),
				  _err_code(0),
				  _common(),
				  _thread_num(0),
				  _thread_queue_size(0),
				  _thread_page_size(0),
				  _thread_capacity_size(0),
				  _service()
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				uint32_t ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + _common.size() + sizeof(_thread_num) +
						sizeof(_thread_queue_size) + sizeof(_thread_page_size) +
						sizeof(_thread_capacity_size) + _service.size() +
						str_sizeof(_mysql_user) + str_sizeof(_mysql_passwd) +
						str_sizeof(_mysql_dbname) + str_sizeof(_mysql_host));
			}
	};

	struct SSBalanceReq : public SSHead
	{
		public :
			SSBalanceReq()
				: SSHead(CONFSVR_CMD_0, SS_BALANCE_REQ)
			{
			}
	};

	struct SSBalanceRes : public SSHead
	{
		public :
			uint16_t       _err_code;

			CommonConf    _common;

			Host          _service;

		public :
			SSBalanceRes()
				: SSHead(CONFSVR_CMD_0, SS_BALANCE_RES),
				  _err_code(0),
				  _common(),
				  _service()
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				uint32_t ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + _common.size() + _service.size()); 
			}
	};

	struct SSAccountReq : public SSHead
	{
		public :
			SSAccountReq()
				: SSHead(CONFSVR_CMD_0, SS_ACCOUNT_REQ)
			{
			}
	};

	struct SSAccountRes : public SSHead
	{
		public :
			uint16_t       _err_code;
			CommonConf    _common;

			Host          _service;
			Host          _dbsvr;

			uint32_t      _dbsvr_timeout;

		public :
			SSAccountRes()
				: SSHead(CONFSVR_CMD_0, SS_ACCOUNT_RES),
				  _err_code(0),
				  _common(),
				  _service(),
				  _dbsvr()
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				int ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + _common.size() + _service.size() + 
						_dbsvr.size() + sizeof(_dbsvr_timeout));
			}
	};

	struct SSHttpClientReq : public SSHead
	{
		public :
			SSHttpClientReq()
				: SSHead(CONFSVR_CMD_0, SS_HTTP_CLIENT_REQ)
			{
			}
	};

	struct SSHttpClientRes : public SSHead
	{
		public :
			uint16_t       _err_code;
			CommonConf     _common;

			Host           _service;
			
			std::string    _url;
			std::string    _version;
			std::string    _appid;
			std::string    _appkey;
			std::string    _pf;
			std::string    _format;

			uint32_t       _http_timeout;

			uint32_t       _thread_num;
		public :
			SSHttpClientRes()
				: SSHead(CONFSVR_CMD_0, SS_HTTP_CLIENT_RES)
			{
			}
			
			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				uint32_t ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + _common.size() +
						_service.size() + str_sizeof(_url) +
						str_sizeof(_version) + str_sizeof(_appid) + str_sizeof(_appkey) +
						str_sizeof(_pf) + str_sizeof(_format) +
						sizeof(_http_timeout) + sizeof(_thread_num));
			}
	};

	typedef ConfigReqTmpl<CONFSVR_CMD_0, SS_GATEWAY_REQ> SSGatewayReq;
	
	struct SSGatewayRes : public SSHead
	{
		public :
			uint16_t       _err_code;
			uint32_t       _timeout;
			
			CommonConf    _common;
		
			Host          _scence;
			Host          _client;

			Host          _http_client;
			Host          _dbsvr;
			Host          _balance;

		public :
			SSGatewayRes()
				: SSHead(CONFSVR_CMD_0, SS_GATEWAY_RES),
				  _err_code(0),
				  _timeout(0),
				  _common(),
				  _scence(),
				  _client(),
				  _http_client(),
				  _dbsvr(),
				  _balance()
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				uint32_t ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + sizeof(_timeout) + _common.size() + \
						_scence.size() + _client.size() + _http_client.size() + \
						_dbsvr.size() + _balance.size());
			}
	};

	typedef ConfigReqTmpl<CONFSVR_CMD_0, SS_SCENCE_REQ> SSScenceReq;
	
	struct SSScenceRes : public SSHead
	{
		public :
			uint16_t                _err_code;
			CommonConf             _common;

			std::vector<Host>      _gateway_list;
			std::vector<AreaConf>  _area_list;

		public :
			SSScenceRes()
				: SSHead(CONFSVR_CMD_0, SS_SCENCE_RES),
				  _err_code(0),
				  _common()
			{
			}

			void serialize(Streamer & streamer);

			const std::string to_string() const;
			
			uint32_t size() const
			{
				uint32_t ret = SSHead::size() + sizeof(_err_code);
				if (0 != _err_code)
				{
					return ret;
				}

				return (ret + _common.size() + 
						vec_sizeof(_gateway_list) + vec_sizeof(_area_list));
			}
	};
};

#endif

